// 1.将下面异步代码使用 Promise 的方式改进
// setTimeout(function () {
//   var a = 'hello'
//   setTimeout(function () {
//     var b = 'lagou'
//     setTimeout(function () {
//       var c = 'I ❤️ U'
//       console.log(a + b + c)
//     }, 10);
//   }, 10);
// }, 10);

Promise.resolve('hello').then(a => a + 'lagou').then(b => b + 'I ❤️ U').then(c => console.log(c))

// 基于以下代码完成下面的四个练习
const fp = require('lodash/fp')
// 数据：horsepower 马力，dollar_value 价格，in_stock 库存
const cars = [
  { name: 'Ferrari FF', horsepower: 660, dollar_value: 700000, in_stock: true },
  { name: 'Spyker C12 Zagato', horsepower: 650, dollar_value: 648000, in_stock: false },
  { name: 'Jaguar XKR-S', horsepower: 550, dollar_value: 132000, in_stock: false },
  { name: 'Audi R8', horsepower: 525, dollar_value: 114200, in_stock: false },
  { name: 'Aston Martin One-77', horsepower: 750, dollar_value: 185000, in_stock: true },
  { name: 'Pagani Huayra', horsepower: 700, dollar_value: 130000, in_stock: false }
]
// 练习1：使用组合函数 fp.flowRight() 重新实现下面这个函数
// let isLastInStock = function (cars) {
//   // 获取最后一条数据
//   let last_car = fp.last(cars)
//   // 获取最后一条数据的 in_stock 属性值
//   return fp.prop('in_stock', last_car)
// }
let getPropValue = function (key) {
  return fp.curry(fp.prop)(key)
}
let isLastInStock = fp.flowRight(getPropValue('in_stock'), fp.last)
// console.log(isLastInStock(cars))


// 练习2：使用 fp.flowRight()、fp.prop() 和 fp.first() 获取第一个 car 的 name
// 先定义获取第一条数据的函数，再定义获取某个对象中的 name 属性的函数，再用 fp.flowRight 组合函数
let isFirstInStock = fp.flowRight(getPropValue('name'), fp.first)
// console.log(isFirstInStock(cars))

// 练习3：使用帮助函数 _average 重构 averageDollarValue，使用函数组合的方式实现
let _average = function (xs) {
  return fp.reduce(fp.add, 0, xs) / xs.length
}
let averageDollarValue = function (cars) {
  // return cars.dollar_value
  let dollar_values = fp.map(
    function (car) {
      return car.dollar_value
    }, cars)
  return _average(dollar_values)
}
let _averageDollarValue = fp.flowRight(_average, fp.map(car => car.dollar_value))
// console.log(_averageDollarValue(cars))

// 练习4：使用 flowRight 写一个 sanitizeNames() 函数，返回一个下划线连续的小写字符串，把数组中的 name 转换为这种形式，例如：sanitizeNames(["Hello World"]) => ["hello_world"]
let _underscore = fp.replace(/\W+/g, '_')
let sanitizeNames = fp.flowRight(fp.map(name => _underscore(name)), fp.map(car => car.name))
// console.log(sanitizeNames(cars))

// 三、基于下面提供的代码，完成后续的四个练习
// 练习1：使用 fp.add(x, y) 和 fp.map(f,x) 创建一个能让 functor 里的值增加的函数 ex1
const { Maybe, Container } = require('./support')
let maybe = Maybe.of([5, 6, 1])

let ex1 = value => {
  return fp.map(fp.add(1), value)
}
// console.log(maybe.map(ex1))


// 练习2：实现一个函数 ex2，能够使用 fp.first 获取列表的第一个元素
let xs = Container.of(['do', 'ray', 'me', 'fa', 'so', 'la', 'ti', 'do'])
let ex2 = value => {
  // 你需要实现的函数。。。
  return fp.first(value)
}
// console.log(xs.map(ex2))

// 练习3：实现一个函数 ex3，使用 safeProp 和 fp.first 找到 user 的名字的首字母
let safeProp = fp.curry(function (x, o) {
  return Maybe.of(o[x])
})
let user = { id: 2, name: 'Albert' }
let ex3 = o => {
  return safeProp('name', o).map(name => fp.first(name))
}
// console.log(ex3(user))

// 练习4：使用 Maybe 重写 ex4，不要有 if 语句
let ex4 = function (n) {
  if (n) {
    return parseInt(n)
  }
}

ex4 = n => Maybe.of(n).map(n => parseInt(n))
// console.log(ex4(null))
// console.log(ex4(3))